﻿using UnityEngine;
using System;
using ProtoBuf;

/// <summary>
/// 协议类型（1000-10000,保证协议类型3个字节）
/// </summary>
public enum MsgType
{
    回调 = 1000,

    推送,
    心跳,
    同步,

    连接,
    公告,
}

#region 协议数据

/// <summary>
/// 公有数据
/// </summary>
public class CommonData
{
    /// <summary>
    /// 逻辑更新间隔（毫秒）
    /// </summary>
    public const int UPDATE_INTERVAL = 100;
    /// <summary>
    /// 逻辑更新间隔（秒）
    /// </summary>
    public static float UPDATE_INTERVAL_SECOND { get { return UPDATE_INTERVAL * 0.001f; } }
}

/// <summary>
/// 传输用的Color
/// </summary>
[ProtoContract]
public struct MyColor
{
    [ProtoMember(1)]
    public float r;
    [ProtoMember(2)]
    public float g;
    [ProtoMember(3)]
    public float b;
    [ProtoMember(4)]
    public float a;

    public Color ToUnity { get { return new Color(r, g, b, a); } }

    public MyColor(Color color) : this(color.r, color.g, color.b, color.a)
    {

    }

    public MyColor(float r, float g, float b, float a = 1)
    {
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a;
    }

    public override string ToString()
    {
        string result = r.ToString() + "," + g.ToString() + "," + b.ToString() + "," + a.ToString();
        return result.Format();
    }
}

/// <summary>
/// 传输用的Vector3
/// </summary>
[ProtoContract]
public struct MyVector3
{
    [ProtoMember(1)]
    public float x;
    [ProtoMember(2)]
    public float y;
    [ProtoMember(3)]
    public float z;

    public static readonly MyVector3 ZERO = new MyVector3(0, 0, 0);
    public static readonly MyVector3 ONE = new MyVector3(1, 1, 1);

    public Vector3 ToUnity { get { return new Vector3(x, y, z); } }

    public MyVector3(Vector3 v) : this(v.x, v.y, v.z)
    {

    }

    /// <summary>
    /// 初始化MyVector3
    /// </summary>
    /// <param name="x">x</param>
    /// <param name="y">y</param>
    /// <param name="z">z</param>
    /// <param name="keep">保留2位小数</param>
    public MyVector3(float x, float y, float z, int keep = 2)
    {
        this.x = (float)Math.Round(x, keep);
        this.y = (float)Math.Round(y, keep);
        this.z = (float)Math.Round(z, keep);
    }

    public override string ToString()
    {
        string result = x.ToString() + "," + y.ToString() + "," + z.ToString();
        return result.Format();
    }

    /// <summary>
    /// 比较目标数据是否和自己的值相等（基于性能就不重写Equals和GetHashCode了）
    /// </summary>
    /// <param name="vector">目标数据</param>
    /// <returns>是否值相等</returns>
    public bool Compare(MyVector3 vector)
    {
        bool isEquals = x == vector.x &&
                        y == vector.y &&
                        z == vector.z;
        return isEquals;
    }
}

#endregion

#region 信息基类

/// <summary>
/// 结果信息类
/// </summary>
[ProtoContract]
public class ResultData
{
    /// <summary>
    /// 是否错误
    /// </summary>
    [ProtoMember(1)]
    public bool isError = false;
    /// <summary>
    /// 结果信息
    /// </summary>
    [ProtoMember(2)]
    public string info = string.Empty;

    public ResultData() { }

    public ResultData(bool isError, string info = "")
    {
        SetResult(isError, info);
    }

    public override string ToString()
    {
        string str = (isError ? "错" : "对") + (info != "" ? "：" : "") + info;
        return str.Format();
    }

    /// <summary>
    /// 设置结果信息
    /// </summary>
    /// <param name="isError">是否失败</param>
    /// <param name="info">返回信息</param>
    public void SetResult(bool isError, string info = "")
    {
        this.isError = isError;
        this.info = info;
    }
}

#endregion

#region 登陆注册

/// <summary>
/// 用户账户信息
/// </summary>
[ProtoContract]
public class UserData
{
    [ProtoMember(1)]
    public string userName = string.Empty;
    /// <summary>
    /// 密码
    /// </summary>
    [ProtoMember(2)]
    public string passWord = string.Empty;

    /// <summary>
    /// Sha256后的密码
    /// </summary>
    public string PassWord { get { return passWord.Sha256(); } }

    public UserData() { }

    public UserData(string userName, string passWord)
    {
        this.userName = userName;
        this.passWord = passWord;
    }

    public override string ToString()
    {
        string p = passWord.Length > 10 ? passWord.Substring(0, 10) + "..." : passWord;
        return (userName + "_" + p).Format();
    }
}

#endregion